package asia.yuanding.wechat.web.netty.handler.impl;

import asia.yuanding.wechat.web.netty.handler.MessageHandlerUtil;
import asia.yuanding.wechat.web.netty.handler.annotation.MessageProcessor;
import asia.yuanding.wechat.web.netty.handler.annotation.NettyMessageHandler;
import asia.yuanding.wechat.web.netty.manager.ChannelManager;
import asia.yuanding.wechat.web.netty.vo.Result;
import cn.hutool.json.JSONObject;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * @ClassName: WebRTCHandler
 * @Author: YuanDing
 * @Date: 2025/8/17
 * @Description: 简单版 WebRTC 信令转发（支持 1v1）
 */
@Data
@Slf4j
@NettyMessageHandler("rtc")
public class WebRTCHandler {


    @MessageProcessor("join")
    public void join(JSONObject reqEntity, ChannelHandlerContext ctx) {
        Map<String , Object> dataMap =  (Map)reqEntity.get("data");
        String roomId = dataMap.getOrDefault("sessionId" , "").toString();
        String userId = MessageHandlerUtil.getUId(ctx);
        String targetUserId = dataMap.get("target").toString(); // 1v1场景下的对方用户ID
        Channel ch = ctx.channel();

        log.info("WebRTC加入房间请求 - 用户ID: {}, 房间ID: {}, 目标用户: {}, 连接ID: {}", 
                userId, roomId, targetUserId, ch.id().asShortText());

        if (userId == null || userId.trim().isEmpty()) {
            log.warn("WebRTC加入房间失败 - 用户ID为空, 连接ID: {}", ch.id().asShortText());
            ch.writeAndFlush(MessageHandlerUtil.getResult(Result.error("用户ID不能为空", null, "rtcError")));
            return;
        }

        if (roomId == null || roomId.trim().isEmpty()) {
            log.warn("WebRTC加入房间失败 - 房间ID为空, 用户ID: {}", userId);
            ch.writeAndFlush(MessageHandlerUtil.getResult(Result.error("房间ID不能为空", null, "rtcError")));
            return;
        }

        // 1. 通知自己加入成功
        JSONObject selfResult = new JSONObject();
        selfResult.set("roomId", roomId);
        selfResult.set("userId", userId);
        selfResult.set("target", targetUserId);
        ch.writeAndFlush(MessageHandlerUtil.getResult(Result.ok("joined", selfResult)));
        
        log.info("WebRTC加入房间成功 - 用户ID: {}, 房间ID: {}", userId, roomId);

        // 2. 如果有目标用户，通知对方有人加入
        if (targetUserId != null && !targetUserId.trim().isEmpty()) {
            Channel targetChannel = ChannelManager.getChannel(targetUserId);
            if (targetChannel != null && targetChannel.isActive()) {
                JSONObject peerJoinNotify = new JSONObject();
                peerJoinNotify.set("roomId", roomId);
                peerJoinNotify.set("userId", userId);
                peerJoinNotify.set("action", "peerJoined");
                
                targetChannel.writeAndFlush(MessageHandlerUtil.getResult(Result.ok("peerJoined", peerJoinNotify)));
                log.info("通知目标用户有人加入房间 - 新用户: {}, 目标用户: {}, 房间ID: {}", userId, targetUserId, roomId);
            } else {
                log.warn("目标用户不在线，无法通知加入 - 新用户: {}, 目标用户: {}, 房间ID: {}", userId, targetUserId, roomId);
            }
        }
    }

    @MessageProcessor("offer")
    public void offer(JSONObject reqEntity, ChannelHandlerContext ctx) {
        log.info("收到WebRTC offer信令，发送者: {}", MessageHandlerUtil.getUId(ctx));
        forwardToPeer(reqEntity, ctx, "offer");
    }

    @MessageProcessor("answer")
    public void answer(JSONObject reqEntity, ChannelHandlerContext ctx) {
        log.info("收到WebRTC answer信令，发送者: {}", MessageHandlerUtil.getUId(ctx));
        forwardToPeer(reqEntity, ctx, "answer");
    }

    @MessageProcessor("candidate")
    public void candidate(JSONObject reqEntity, ChannelHandlerContext ctx) {
        log.debug("收到WebRTC candidate信令，发送者: {}", MessageHandlerUtil.getUId(ctx));
        forwardToPeer(reqEntity, ctx, "candidate");
    }

    private void forwardToPeer(JSONObject reqEntity, ChannelHandlerContext ctx, String type) {
        Map<String , Object> dataMap =  (Map)reqEntity.get("data");
        String targetUserId =  dataMap.getOrDefault("target" , "").toString(); // 前端要带 target
        String fromUserId = MessageHandlerUtil.getUId(ctx);

        log.debug("转发WebRTC {}信令 - 发送者: {}, 接收者: {}", type, fromUserId, targetUserId);

        if (targetUserId == null || targetUserId.trim().isEmpty()) {
            log.warn("WebRTC {}信令转发失败 - 目标用户ID为空, 发送者: {}", type, fromUserId);
            JSONObject err = new JSONObject();
            err.set("message", "目标用户ID不能为空");
            ctx.channel().writeAndFlush(MessageHandlerUtil.getResult(Result.error("目标用户ID不能为空", err, "rtcError")));
            return;
        }

        if (fromUserId == null || fromUserId.trim().isEmpty()) {
            log.warn("WebRTC {}信令转发失败 - 发送者用户ID为空, 目标用户: {}", type, targetUserId);
            JSONObject err = new JSONObject();
            err.set("message", "发送者用户ID不能为空");
            ctx.channel().writeAndFlush(MessageHandlerUtil.getResult(Result.error("发送者用户ID不能为空", err, "rtcError")));
            return;
        }

        Channel targetChannel = ChannelManager.getChannel(targetUserId);
        if (targetChannel != null && targetChannel.isActive()) {
            // 组装转发数据
            JSONObject payload = new JSONObject();
            payload.set("from", fromUserId);
            payload.set("type", type);
            payload.set("data", reqEntity.get("data"));

            targetChannel.writeAndFlush(MessageHandlerUtil.getResult(Result.ok(type, payload)));
            log.info("WebRTC {}信令转发成功 - 发送者: {}, 接收者: {}, 目标连接ID: {}", 
                    type, fromUserId, targetUserId, targetChannel.id().asShortText());
        } else {
            // 目标不在线，通知自己
            log.warn("WebRTC {}信令转发失败 - 目标用户离线或连接已断开, 发送者: {}, 接收者: {}", 
                    type, fromUserId, targetUserId);
            JSONObject err = new JSONObject();
            err.set("target", targetUserId);
            err.set("from", fromUserId);
            ctx.channel().writeAndFlush(MessageHandlerUtil.getResult(Result.error("目标用户不在线", err, "rtcError")));
        }
    }
}
